package 大鱼吃小鱼.BigFishEatSmallFishGame.java.src;

import javax.sound.sampled.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;

public class BigFishEatSmallFishGame extends JFrame {
    private static final int WIDTH = 800;
    private static final int HEIGHT = 600;
    private Fish playerFish;
    private ArrayList<Fish> fishList;
    private Timer timer;
    private int score;
    private JLabel scoreLabel;
    private Clip backgroundMusic;

    public BigFishEatSmallFishGame() {
        initGame();
        initUI();
        playBackgroundMusic();
    }

    private void initGame() {
        playerFish = new Fish(WIDTH / 2, HEIGHT / 2, 50, Color.RED, true);
        fishList = new ArrayList<>();
        score = 0;

        Random random = new Random();
        for (int i = 0; i < 20; i++) {
            int size = random.nextInt(30) + 10;
            int x = random.nextInt(WIDTH - size);
            int y = random.nextInt(HEIGHT - size);
            Color color = new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
            fishList.add(new Fish(x, y, size, color, false));
        }

        timer = new Timer(16, e -> {
            update();
            repaint();
        });
        timer.start();
    }

    private void initUI() {
        setTitle("大鱼吃小鱼");
        setSize(WIDTH, HEIGHT);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        GamePanel gamePanel = new GamePanel();
        add(gamePanel, BorderLayout.CENTER);

        scoreLabel = new JLabel("分数: 0");
        scoreLabel.setFont(new Font("Arial", Font.BOLD, 20));
        add(scoreLabel, BorderLayout.NORTH);

        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                playerFish.keyPressed(e);
            }

            @Override
            public void keyReleased(KeyEvent e) {
                playerFish.keyReleased(e);
            }
        });

        setFocusable(true);
    }

    private void playBackgroundMusic() {
        try {
            File soundFile = new File("C:\\Users\\lenovo\\Desktop\\编程\\面向对象的程序设计\\库\\大鱼吃小鱼\\BigFishEatSmallFishGame.java\\src\\background_music .wav");
            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(soundFile);
            backgroundMusic = AudioSystem.getClip();
            backgroundMusic.open(audioInputStream);
            backgroundMusic.loop(Clip.LOOP_CONTINUOUSLY);
        } catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(this, "无法播放背景音乐", "错误", JOptionPane.ERROR_MESSAGE);
        }
    }

    private void update() {
        playerFish.move();

        for (int i = fishList.size() - 1; i >= 0; i--) {
            Fish fish = fishList.get(i);
            fish.move();

            if (playerFish.getBounds().intersects(fish.getBounds())) {
                if (playerFish.getSize() > fish.getSize()) {
                    playerFish.grow(fish.getSize() / 10);
                    fishList.remove(i);
                    score += fish.getSize();
                    scoreLabel.setText("分数: " + score);

                    Random random = new Random();
                    int size = random.nextInt(30) + 10;
                    int x = random.nextInt(WIDTH - size);
                    int y = random.nextInt(HEIGHT - size);
                    Color color = new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
                    fishList.add(new Fish(x, y, size, color, false));
                } else {
                    timer.stop();
                    backgroundMusic.stop();
                    JOptionPane.showMessageDialog(this, "游戏结束！你的分数是: " + score, "游戏结束", JOptionPane.INFORMATION_MESSAGE);
                    System.exit(0);
                }
            }
        }
    }

    private class GamePanel extends JPanel {
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            setBackground(Color.CYAN);

            playerFish.draw(g);

            for (Fish fish : fishList) {
                fish.draw(g);
            }
        }
    }

    private static class Fish {
        private int x, y;
        private int size;
        private Color color;
        private boolean isPlayer;
        private int dx, dy;
        private static final int MAX_SPEED = 5;
        private Random random;

        public Fish(int x, int y, int size, Color color, boolean isPlayer) {
            this.x = x;
            this.y = y;
            this.size = size;
            this.color = color;
            this.isPlayer = isPlayer;
            random = new Random();

            if (!isPlayer) {
                dx = random.nextInt(3) - 1;
                dy = random.nextInt(3) - 1;
                if (dx == 0 && dy == 0) {
                    dx = 1;
                }
            }
        }

        public void move() {
            if (isPlayer) {
                x += dx;
                y += dy;

                if (x < 0) x = 0;
                if (x > WIDTH - size) x = WIDTH - size;
                if (y < 0) y = 0;
                if (y > HEIGHT - size) y = HEIGHT - size;
            } else {
                x += dx;
                y += dy;

                if (x < 0 || x > WIDTH - size) dx = -dx;
                if (y < 0 || y > HEIGHT - size) dy = -dy;
            }
        }

        public void keyPressed(KeyEvent e) {
            int key = e.getKeyCode();

            if (key == KeyEvent.VK_LEFT) {
                dx = -MAX_SPEED;
            }

            if (key == KeyEvent.VK_RIGHT) {
                dx = MAX_SPEED;
            }

            if (key == KeyEvent.VK_UP) {
                dy = -MAX_SPEED;
            }

            if (key == KeyEvent.VK_DOWN) {
                dy = MAX_SPEED;
            }
        }

        public void keyReleased(KeyEvent e) {
            int key = e.getKeyCode();

            if (key == KeyEvent.VK_LEFT || key == KeyEvent.VK_RIGHT) {
                dx = 0;
            }

            if (key == KeyEvent.VK_UP || key == KeyEvent.VK_DOWN) {
                dy = 0;
            }
        }

        public void draw(Graphics g) {
            g.setColor(color);
            g.fillOval(x, y, size, size / 2);

            g.setColor(Color.WHITE);
            int eyeSize = size / 10;
            if (dx >= 0) {
                g.fillOval(x + size - eyeSize * 2, y + size / 4 - eyeSize / 2, eyeSize, eyeSize);
            } else {
                g.fillOval(x + eyeSize, y + size / 4 - eyeSize / 2, eyeSize, eyeSize);
            }

            g.setColor(Color.BLACK);
            if (dx >= 0) {
                g.fillOval(x + size - eyeSize * 2 + eyeSize / 3, y + size / 4 - eyeSize / 2 + eyeSize / 3, eyeSize / 2, eyeSize / 2);
            } else {
                g.fillOval(x + eyeSize + eyeSize / 3, y + size / 4 - eyeSize / 2 + eyeSize / 3, eyeSize / 2, eyeSize / 2);
            }

            g.setColor(color.darker());
            if (dx >= 0) {
                int[] xPoints = {x, x - size / 4, x};
                int[] yPoints = {y + size / 4, y + size / 2, y + size * 3 / 4};
                g.fillPolygon(xPoints, yPoints, 3);
            } else {
                int[] xPoints = {x + size, x + size + size / 4, x + size};
                int[] yPoints = {y + size / 4, y + size / 2, y + size * 3 / 4};
                g.fillPolygon(xPoints, yPoints, 3);
            }
        }

        public Rectangle getBounds() {
            return new Rectangle(x, y, size, size / 2);
        }

        public int getSize() {
            return size;
        }

        public void grow(int amount) {
            size += amount;
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            BigFishEatSmallFishGame game = new BigFishEatSmallFishGame();
            game.setVisible(true);
        });
    }
}